
    function ActionHandler(config, param, container, target) {
		this.param = config.param;
		this.model = {};
		this.view = undefined;
		this.target = target;
		this.config = config;
		this.container = container;
		this._def = $.Deferred();
	}
	
	ActionHandler.prototype = {
		refresh : function() {
			$ts.load(this.config.action, this.param, this.view);
		},	
		navigateTo : function(action, param) {
			if (!this.view) {
				this.view = $(this.target).closest(PAGE_SELECTOR);
			}
			
			$ts.load(action.indexOf(".") < 0 ? this.config.namespace + "." + action : action, param, this.view);
		},
		render : function(callback) {
			var viewPath = $ts.TMPL_PATH + this.config.namespace.replace(/\./g, "/") + "/" + this.config.view + ".html",
                data = {
                    param : this.param,
                    model : this.model
                },
                _this = this;

			$.ajax(viewPath, {
				success : function(result) {
					_this.view = $ts.compile("<div data-box='"+_this.config.namespace+"'>" + result + "</div>", data);
					_this.view.data("controller", _this.config.namespace);
					
					if (typeof (callback) === "undefined") {
						_this.renderEnd();
					} else {
						callback();
					}
				},
				error : function(e){
					emit($ts.ERROR, e);
				},
				dataType : "html",
				cache : true
			});
			
			return this._def.promise();
		},
		_renderComponent : function() {
            var _this = this;
            
			this.view.find("[ts-type]").each(function(index, com) {
				var _types = $(this).attr("ts-type").split(" ");
				
				for (var i = _types.length; i--;) {
					var _type = _types[i];
					require.async($ts.COMPONENT_PACKAGE + _type, function(Component) {
						try {
							Component.init($(com), _this.model, _this.param, $ts);
						} catch(e){
							emit($ts.ERROR, e);
						}
					});
				}
			});
		},
		renderEnd : function() {
			this._renderComponent();
			if (this.container.attr("data-box")) {
				this.container.after(this.view);
				this.container.remove();
			} else {
				this.container.empty();
				this.container.append(this.view);
			}
			
			_def.resolve();
			emit($ts.AFTER_LOAD, {action : this.config.action, param : this.param, container : this.container});
		}
	};